﻿using System;
using Validate.Net.Core;

namespace Validate.Net.Internals
{

    /// <summary>
    /// 属性只能在给定的区间内
    /// </summary>
    /// <exception cref="ArgumentException"/>
    public class RangeAttribute : ValidateBaseAttribute
    {
        /// <summary>
        /// 属性只能在给定的区间内。
        /// <param name="internalPrompts">内联提示语</param>
        /// </summary>
        public RangeAttribute(string internalPrompts = null) : base(internalPrompts)
        {

        }

        /// <summary>
        /// 区间下界，包括下界。
        /// <see cref="IComparable"/> 类型的值
        /// </summary>
        public object Minimum { get; set; } = RangeValue.Infinity;

        /// <summary>
        /// 区间上界，包括上界。
        /// <see cref="IComparable"/> 类型的值
        /// </summary>
        public object Maximum { get; set; } = RangeValue.Infinity;

        public override string Prompts => string.Format(Properties.Resources.RangePrompts, Minimum.ToString("-"), Maximum.ToString("+"));

        public override bool OnCheck(object value)
        {
            if (value == null) { return false; }

            var valueType = value.GetType();

            if (!(Minimum is RangeValue) && Minimum.GetType() != valueType)
            { throw new ArgumentException($"属性 {nameof(Minimum)} 必须是 {valueType.FullName} 类型"); }
            if (!(Maximum is RangeValue) && Maximum.GetType() != valueType)
            { throw new ArgumentException($"属性 {nameof(Maximum)} 必须是 {valueType.FullName} 类型"); }

            if (value is IComparable comparable)
            {
                if (Minimum is RangeValue.Infinity && Maximum is RangeValue.Infinity) { return true; }
                else if (Minimum is RangeValue.Infinity)
                { return comparable.CompareTo(Maximum) <= 0; }
                else if (Maximum is RangeValue.Infinity)
                { return comparable.CompareTo(Minimum) >= 0; }
                else { return comparable.CompareTo(Minimum) >= 0 && comparable.CompareTo(Maximum) <= 0; }
            }
            else
            { throw new ArgumentException($"特性 {nameof(RangeAttribute)} 只能修饰实现了 {nameof(IComparable)} 接口的属性"); }
        }
    }
}
